﻿#pragma once
#include"stdafx.h"
/*
Z 字形变换
将一个给定字符串根据给定的行数，以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时，排列如下：

L   C   I   R
E T O E S I I G
E   D   H   N
之后，你的输出需要从左往右逐行读取，产生出一个新的字符串，比如："LCIRETOESIIGEDHN"。

请你实现这个将字符串进行指定行数变换的函数：

string convert(string s, int numRows);
示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

解题思路：
我的解题想法，拿到题目后，我当然想到不能去变换，这个题目可以说是很有意思了，
有点规律性，比如numRows为n时，n-1的下标就是就是Z形状的角，每个元素都是关于角对称的，
因此每一行数据都是固定的，只要遍历一遍，便可以得到答案，时间复杂度是O(n).
*/

string convert(string s, int numRows) 
{
	int length = s.size();
	if (length <= numRows || numRows ==1) //当小与等于numRows，结果就是源string
	{
		return s;
	}


	int index = numRows - 1; //下标减一
	string str = "";
	for (int i = 0; i<= index;i++)
	{
		int cur = i;
		for (int j = 0; j<length; j+= index)
		{
			if (i == 0)
			{
				if (2 * j <length)
				{
					str += s[cur+ 2 * j];
				}
				else
				{
					break;
				}
				
			}
			else if (i == index)
			{
				if (2 * j + cur <length)
				{
					str += s[cur +2 * j ];
				}
				else
				{
					break;
				}
			}//当为中间的数据的时候
			else
			{
				int dif = abs(j - cur);
				cur = dif + j;
				if (cur >= length)
				{
					break;
				}
				str += s[cur];
			}
			
		}
	}
	return str;
}

void testconvert()
{
	string str1 = "PAYPALISHIRING";

	string str = convert(str1, 3);

	cout << "the ans  is : " << str << endl;

}
